<!DOCTYPE html>
<html>
<head>
    <title>Piston Cylinder Diagram</title>
</head>
<body>
<canvas id="physicsCanvas" width="800" height="420"></canvas>
<script>
    const canvas = document.getElementById('physicsCanvas');
    const ctx = canvas.getContext('2d');

    // --- Helper function to draw an arrowed line ---
    function drawArrowLine(ctx, x1, y1, x2, y2) {
        ctx.beginPath();
        ctx.moveTo(x1, y1);
        ctx.lineTo(x2, y2);
        ctx.stroke();

        const arrowHeadSize = 8;
        const angle = Math.atan2(y2 - y1, x2 - x1);

        // Arrow head at the end (x2, y2)
        ctx.beginPath();
        ctx.moveTo(x2, y2);
        ctx.lineTo(x2 - arrowHeadSize * Math.cos(angle - Math.PI / 6), y2 - arrowHeadSize * Math.sin(angle - Math.PI / 6));
        ctx.lineTo(x2 - arrowHeadSize * Math.cos(angle + Math.PI / 6), y2 - arrowHeadSize * Math.sin(angle + Math.PI / 6));
        ctx.closePath();
        ctx.fill();

        // Arrow head at the start (x1, y1)
        const angle_rev = Math.atan2(y1 - y2, x1 - x2);
        ctx.beginPath();
        ctx.moveTo(x1, y1);
        ctx.lineTo(x1 - arrowHeadSize * Math.cos(angle_rev - Math.PI / 6), y1 - arrowHeadSize * Math.sin(angle_rev - Math.PI / 6));
        ctx.lineTo(x1 - arrowHeadSize * Math.cos(angle_rev + Math.PI / 6), y1 - arrowHeadSize * Math.sin(angle_rev + Math.PI / 6));
        ctx.closePath();
        ctx.fill();
    }


    // --- Main Drawing ---
    ctx.strokeStyle = 'black';
    ctx.fillStyle = 'black';
    ctx.lineWidth = 2;
    ctx.font = '18px Arial';

    const cylinderWidth = 140;
    const cylinderInnerHeight = 230;
    const wallThickness = 20;
    const pistonHeight = 40;

    // --- Left Diagram (Maximum Height) ---
    const x_left = 100;
    const y_top = 50;

    // Draw cylinder
    ctx.fillStyle = '#D3D3D3'; // Gray color for cylinder walls
    ctx.fillRect(x_left, y_top, wallThickness, cylinderInnerHeight + wallThickness); // Left wall
    ctx.fillRect(x_left + cylinderWidth + wallThickness, y_top, wallThickness, cylinderInnerHeight + wallThickness); // Right wall
    ctx.fillRect(x_left, y_top + cylinderInnerHeight, cylinderWidth + 2 * wallThickness, wallThickness); // Bottom wall
    ctx.fillStyle = 'black'; // Reset fill color

    // Draw piston at maximum height
    const piston_x_left = x_left + wallThickness;
    const piston_y_max = y_top + 40;
    ctx.strokeRect(piston_x_left, piston_y_max, cylinderWidth, pistonHeight);
    // Piston rings
    ctx.beginPath();
    ctx.lineWidth = 1;
    ctx.moveTo(piston_x_left, piston_y_max + 10);
    ctx.lineTo(piston_x_left + cylinderWidth, piston_y_max + 10);
    ctx.moveTo(piston_x_left, piston_y_max + 15);
    ctx.lineTo(piston_x_left + cylinderWidth, piston_y_max + 15);
    ctx.moveTo(piston_x_left, piston_y_max + 20);
    ctx.lineTo(piston_x_left + cylinderWidth, piston_y_max + 20);
    ctx.stroke();
    ctx.lineWidth = 2;

    // Labels for left diagram
    ctx.textAlign = 'right';
    ctx.fillText('cylinder', x_left - 15, y_top + 40);
    ctx.beginPath();
    ctx.moveTo(x_left - 10, y_top + 50);
    ctx.lineTo(x_left + wallThickness, y_top + 65);
    ctx.stroke();

    ctx.fillText('piston', x_left - 15, piston_y_max + 25);
    ctx.beginPath();
    ctx.moveTo(x_left - 10, piston_y_max + 20);
    ctx.lineTo(piston_x_left, piston_y_max + 12);
    ctx.stroke();

    ctx.textAlign = 'center';
    ctx.fillText('maximum height', x_left + (cylinderWidth / 2) + wallThickness, y_top + cylinderInnerHeight + wallThickness + 40);


    // --- Right Diagram (Minimum Height) ---
    const x_right = 500;

    // Draw cylinder
    ctx.fillStyle = '#D3D3D3';
    ctx.fillRect(x_right, y_top, wallThickness, cylinderInnerHeight + wallThickness);
    ctx.fillRect(x_right + cylinderWidth + wallThickness, y_top, wallThickness, cylinderInnerHeight + wallThickness);
    ctx.fillRect(x_right, y_top + cylinderInnerHeight, cylinderWidth + 2 * wallThickness, wallThickness);
    ctx.fillStyle = 'black';

    // Piston travel distance (visual representation)
    const travel_distance = 150;
    const piston_y_min = piston_y_max + travel_distance;
    const piston_x_right = x_right + wallThickness;

    // Draw piston at minimum height
    ctx.strokeRect(piston_x_right, piston_y_min, cylinderWidth, pistonHeight);
    // Piston rings
    ctx.beginPath();
    ctx.lineWidth = 1;
    ctx.moveTo(piston_x_right, piston_y_min + 10);
    ctx.lineTo(piston_x_right + cylinderWidth, piston_y_min + 10);
    ctx.moveTo(piston_x_right, piston_y_min + 15);
    ctx.lineTo(piston_x_right + cylinderWidth, piston_y_min + 15);
    ctx.moveTo(piston_x_right, piston_y_min + 20);
    ctx.lineTo(piston_x_right + cylinderWidth, piston_y_min + 20);
    ctx.stroke();
    ctx.lineWidth = 2;


    // Labels for right diagram
    ctx.textAlign = 'left';
    ctx.fillText('cylinder', x_right + cylinderWidth + 2 * wallThickness + 15, y_top + 40);
    ctx.beginPath();
    ctx.moveTo(x_right + cylinderWidth + 2 * wallThickness + 10, y_top + 50);
    ctx.lineTo(x_right + cylinderWidth + wallThickness, y_top + 65);
    ctx.stroke();

    ctx.fillText('piston', x_right + cylinderWidth + 2 * wallThickness + 15, piston_y_min + 25);
    ctx.beginPath();
    ctx.moveTo(x_right + cylinderWidth + 2 * wallThickness + 10, piston_y_min + 20);
    ctx.lineTo(piston_x_right + cylinderWidth, piston_y_min + 12);
    ctx.stroke();

    ctx.textAlign = 'center';
    ctx.fillText('minimum height', x_right + (cylinderWidth / 2) + wallThickness, y_top + cylinderInnerHeight + wallThickness + 40);


    // --- Measurement Annotation ---
    const annotation_x = (x_left + cylinderWidth + 2 * wallThickness + x_right) / 2;
    const y_dashed_top = piston_y_max;
    const y_dashed_bottom = piston_y_min;

    // Dashed lines
    ctx.beginPath();
    ctx.setLineDash([5, 5]);
    ctx.lineWidth = 1;
    ctx.moveTo(x_left + cylinderWidth + 2 * wallThickness, y_dashed_top);
    ctx.lineTo(annotation_x, y_dashed_top);
    ctx.moveTo(x_right, y_dashed_bottom);
    ctx.lineTo(annotation_x, y_dashed_bottom);
    ctx.stroke();
    ctx.setLineDash([]); // Reset to solid line

    // Vertical arrow line
    ctx.lineWidth = 1.5;
    drawArrowLine(ctx, annotation_x, y_dashed_top, annotation_x, y_dashed_bottom);

    // Text label
    ctx.textAlign = 'left';
    ctx.fillText('9.8 cm', annotation_x + 10, (y_dashed_top + y_dashed_bottom) / 2 + 6);


    // --- Figure Caption ---
    ctx.lineWidth = 2; // Reset line width
    ctx.textAlign = 'center';
    ctx.fillText('Fig. 3.1', canvas.width / 2, canvas.height - 10);

</script>
</body>
</html>